package com.hanliy.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.hanliy.properties.AlipayProperties;
import com.hanliy.utils.OrderCodeUtils;
import com.ijpay.alipay.AliPayApi;
import com.ijpay.alipay.AliPayApiConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author hanyulin
 * @apiNote
 * @date 2022/2/8 14:27
 */
@RestController
@RequestMapping(value = "/aliPay")
@Slf4j
public class OrderController {

    @Autowired
    private AlipayProperties alipayProperties;

    public AliPayApiConfig getApiConfig() {
        AliPayApiConfig aliPayApiConfig = AliPayApiConfig.builder()
                .setAppId(alipayProperties.getAppId())
                .setAliPayPublicKey(alipayProperties.getPublicKey())
                .setPrivateKey(alipayProperties.getPrivateKey())
                .setServiceUrl(alipayProperties.getServiceUrl())
                .setCharset("UTF-8")
                .setSignType("RSA2")
                // 证书模式
                // .setAppCertPath(alipayProperties.getAppCertPath())
                // .setAliPayCertPath(alipayProperties.getAliPayCertPath())
                // .setAliPayRootCertPath(alipayProperties.getAliPayRootCertPath())
                // 普通公钥方式
                .build();
                // 证书模式
                // .buildByCert();
        return aliPayApiConfig;
    }

    /**
     * 扫码支付
     *
     * @return java.lang.String
     * @date 2022/2/9 11:34
     */
    @GetMapping(value = "/tradePreCreatePay")
    public String tradePreCreatePay() {

        String notifyUrl = alipayProperties.getDoMain() + "/aliPay/aliPayNotifyUrl";

        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setSubject("Javen 支付宝扫码支付测试");
        model.setTotalAmount("10");
        model.setStoreId("123");
        model.setTimeoutExpress("5m");
        String orderNo = OrderCodeUtils.getRandom();
        model.setOutTradeNo(orderNo);
        log.debug("扫码支付创建的订单号={}", orderNo);
        try {
            AlipayTradePrecreateResponse response = AliPayApi.tradePrecreatePayToResponse(model, notifyUrl);
            String resultStr = response.getBody();
            JSONObject jsonObject = JSONObject.parseObject(resultStr);
            return jsonObject.getJSONObject("alipay_trade_precreate_response").getString("qr_code");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 支付回调
     *
     * @param request 请求体
     * @return java.lang.String
     * @date 2022/2/9 11:34
     */
    @PostMapping(value = "/aliPayNotifyUrl")
    public String aliPayNotifyUrl(HttpServletRequest request) {
        try {
            // 获取支付宝POST过来反馈信息
            Map<String, String> params = AliPayApi.toMap(request);
            // 遍历打印出反馈信息
            // for (Map.Entry<String, String> entry : params.entrySet()) {
            //     System.out.println(entry.getKey() + " = " + entry.getValue());
            // }

            boolean verifyResult = AlipaySignature.rsaCheckV1(params, alipayProperties.getPublicKey(), "UTF-8", "RSA2");

            if (verifyResult) {
                // TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
                System.out.println("notify_url 验证成功succcess");
                return "success";
            } else {
                System.out.println("notify_url 验证失败");
                // TODO
                return "failure";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "failure";
        }
    }

    /**
     * 关闭订单
     *
     * @param outTradeNo 商家内部订单号
     * @date 2022/2/9 11:53
     * @return java.lang.String
     */
    @GetMapping(value = "/tradeClose")
    public String tradeClose(@RequestParam("outTradeNo") String outTradeNo){
        try {
            AlipayTradeCloseModel closeModel = new AlipayTradeCloseModel();
            closeModel.setOutTradeNo(outTradeNo);
            return AliPayApi.tradeCloseToResponse(closeModel).getBody();
        } catch (AlipayApiException e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 支付退款
     *
     * @param outTradeNo 商家内部订单号
     * @date 2022/2/9 15:38
     * @return java.lang.String
     */
    @GetMapping(value = "/tradeRefund")
    public String tradeRefund(@RequestParam("outTradeNo") String outTradeNo){
        try {
            AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();
            refundModel.setOutTradeNo(outTradeNo);
            refundModel.setRefundAmount("10");
            refundModel.setRefundReason("退款测试");
            return AliPayApi.tradeRefundToResponse(refundModel).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 订单查询
     *
     * @param outTradeNo 商家内部订单号
     * @date 2022/2/9 15:37
     * @return java.lang.String
     */
    @GetMapping(value = "/tradeQuery")
    public String tradeQuery(@RequestParam("outTradeNo") String outTradeNo){
        AlipayTradeQueryModel queryModel = new AlipayTradeQueryModel();
        queryModel.setOutTradeNo(outTradeNo);
        try {
            AlipayTradeQueryResponse queryResponse = AliPayApi.tradeQueryToResponse(queryModel);
            return queryResponse.getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 退款查询
     *
     * @param outTradeNo 商户内部交易号
     * @date 2022/2/9 15:47
     * @return java.lang.String
     */
    @GetMapping(value = "/refundQuery")
    public String refundQuery(@RequestParam("outTradeNo") String outTradeNo){
        AlipayTradeFastpayRefundQueryModel refundQueryModel = new AlipayTradeFastpayRefundQueryModel();
        refundQueryModel.setOutTradeNo(outTradeNo);
        refundQueryModel.setOutRequestNo(outTradeNo);
        try {
            return AliPayApi.tradeRefundQueryToResponse(refundQueryModel).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }

}
